package com.fiberhome.student;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.Scanner;

/**
 * Hello world!
 * 
 */
public class App {
	public static void main(String[] args) throws IOException {
		printComment();
		
		String projectPath = App.class.getProtectionDomain().getCodeSource().getLocation().getPath();
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(
				projectPath + "/student.txt", false), "UTF-8"));

		System.out.println("请输入班级人数（5 ~ 500）：");
		int stuCnt = readStuCnt(null);
		List<Student> students = new ArrayList<Student>();

		Random random = new Random();
		for (int i = 0; i < stuCnt; i++) {
			students.add(new Student(generateStuNm(i), generateStuNo(i), random.nextInt(101), random.nextInt(101),
					random.nextInt(101)));// 随机生成学分
		}

		// --------------------------------------------------------------------------
		// 1. 输出全部学生信息
		print(bw, String.format(Locale.CHINESE, "%s\t%s\t%s\t%s\t%s\t%s", "姓名", "学号", "语文", "数学", "英语", "总分"));
		for (int i = 0; i < stuCnt; i++) {
			print(bw, students.get(i).toString());
		}

		// --------------------------------------------------------------------------
		// 2. 语文Top3
		Collections.sort(students, new Comparator<Student>() {
			public int compare(Student o1, Student o2) {
				return o2.getChinese().compareTo(o1.getChinese());
			}
		});
		print(bw, "\r\n语文Top3：");
		print(bw, String.format(Locale.CHINESE, "%s\t%s\t%s\t", "姓名", "学号", "语文"));
		for (int i = 0; i < 3; i++) {
			print(bw, String.format(Locale.CHINESE, "%s\t%s\t%s\t", students.get(i).getName(), students.get(i)
					.getNumber(), students.get(i).getChinese()));
		}

		// --------------------------------------------------------------------------
		// 3. 数学Top3
		Collections.sort(students, new Comparator<Student>() {
			public int compare(Student o1, Student o2) {
				return o2.getMathematics().compareTo(o1.getMathematics());
			}
		});
		print(bw, "\r\n数学Top3：");
		print(bw, String.format(Locale.CHINESE, "%s\t%s\t%s\t", "姓名", "学号", "数学"));
		for (int i = 0; i < 3; i++) {
			print(bw, String.format(Locale.CHINESE, "%s\t%s\t%s\t", students.get(i).getName(), students.get(i)
					.getNumber(), students.get(i).getMathematics()));
		}

		// --------------------------------------------------------------------------
		// 4. 英语Top3
		Collections.sort(students, new Comparator<Student>() {
			public int compare(Student o1, Student o2) {
				return o2.getEnglish().compareTo(o1.getEnglish());
			}
		});
		print(bw, "\r\n英语Top3：");
		print(bw, String.format(Locale.CHINESE, "%s\t%s\t%s\t", "姓名", "学号", "英语"));
		for (int i = 0; i < 3; i++) {
			print(bw, String.format(Locale.CHINESE, "%s\t%s\t%s\t", students.get(i).getName(), students.get(i)
					.getNumber(), students.get(i).getEnglish()));
		}

		// --------------------------------------------------------------------------
		// 5. 总分Top3
		Collections.sort(students, new Comparator<Student>() {
			public int compare(Student o1, Student o2) {
				return o2.getTotal().compareTo(o1.getTotal());
			}
		});
		print(bw, "\r\n总成绩Top3：");
		print(bw, String.format(Locale.CHINESE, "%s\t%s\t%s\t", "姓名", "学号", "总分"));
		for (int i = 0; i < 3; i++) {
			print(bw, String.format(Locale.CHINESE, "%s\t%s\t%s\t", students.get(i).getName(), students.get(i)
					.getNumber(), students.get(i).getTotal()));
		}

		// --------------------------------------------------------------------------
		// 6. 平均分
		// 语文计算器
		StudentCacl<Student> chineseCacl = new StudentCacl<Student>(students, new Gettor<Student>() {
			public Integer getProperty(Student t) {
				return t.getChinese();
			}
		});
		// 数学计算器
		StudentCacl<Student> mathematicsCacl = new StudentCacl<Student>(students, new Gettor<Student>() {
			public Integer getProperty(Student t) {
				return t.getMathematics();
			}
		});
		// 英语计算器
		StudentCacl<Student> englishCacl = new StudentCacl<Student>(students, new Gettor<Student>() {
			public Integer getProperty(Student t) {
				return t.getEnglish();
			}
		});

		print(bw, "\r\n各科平均分：");
		print(bw, String.format("语文：%.1f，	最高：%d，	最低：%d", chineseCacl.getAvg(), chineseCacl.getMax(),
				chineseCacl.getMin()));
		print(bw, String.format("数学：%.1f，	最高：%d，	最低：%d", mathematicsCacl.getAvg(), mathematicsCacl.getMax(),
				mathematicsCacl.getMin()));
		print(bw, String.format("英语：%.1f，	最高：%d，	最低：%d", englishCacl.getAvg(), englishCacl.getMax(),
				englishCacl.getMin()));

		bw.close();
	}


	// ---------------------------------以下都是共通函数--------------------------------start
	/**
	 * 从键盘读取一个5~500之间的整数
	 * 
	 * @param scanner
	 * @return
	 */
	private static int readStuCnt(Scanner scanner) {
		int stuCnt = -1;
		if (scanner == null) {
			scanner = new Scanner(System.in);
		}

		try {
			stuCnt = Integer.parseInt(scanner.nextLine());
			if (stuCnt < 5 || stuCnt > 500) {
				throw new Exception();
			}

		} catch (Exception e) {
			System.out.println("请输入5 ~ 50之间的整数!");
			stuCnt = readStuCnt(scanner);
		}

		return stuCnt;
	}

	/**
	 * 按序号生成学生姓名
	 * 
	 * @param squence
	 * @return
	 */
	private static String generateStuNm(int squence) {
		int first = squence / 26;
		int second = squence % 26;

		char firstChar = (char) (first + 65);
		char seconfChar = (char) (second + 65);
		return "Name" + firstChar + seconfChar;
	}

	/**
	 * 按序号生成学生学号
	 * 
	 * @param squence
	 * @return
	 */
	private static String generateStuNo(int squence) {
		return String.format("%03d", squence + 1);
	}

	/**
	 * 按序号生成学生学号
	 * 
	 * @param squence
	 * @return
	 * @throws IOException
	 */
	private static void print(BufferedWriter bw, String line) throws IOException {
		line += "\r\n";
		
		bw.write(line);
		System.out.print(line);
	}
	
	private static void printComment() {
		System.out.print("/* ***********************************************************" + Cons.R_N);
		System.out.print(" * Author: 刘剑" + Cons.R_N);
		System.out.print(" * Date: 2013-9-12" + Cons.R_N);
		System.out.print(" * Comment: 随机产生一批学生及其学分, 进行一系列统计工作" + Cons.R_N);
		System.out.print(" ************************************************************ */" + Cons.R_N);
		
	}
}
